from flask import render_template,redirect,url_for,session, flash, jsonify, request
from flask_login import login_required, current_user
#from flaskext.uploads import UploadSet, IMAGES

from werkzeug.utils import secure_filename
from bson.objectid import ObjectId

from lib.form import Form
from dao.house import HouseDao
#from dao.apartment import ApartmentDao
#from dao.room import RoomDao
from dao.user import UserDao
from dao.city import CityDao
from dao.address import AddressDao
from dao.category import CategoryDao
from dao.advertisement import AdvertisementDao

from dao.session import SessionDao

from model.address import Address
from model.house import House
from model.category import Category
from model.advertisement import Advertisement
from model.picture import Picture
from service.picture import PictureService
#from dao.picture import PictureDao

from service.advertisement import AdvertisementService
from service.file import FileService


from controller import app

import time

IMAGES = tuple('jpg jpe jpeg png gif svg bmp'.split())

class AdvertisementForm(Form):
    def __init__(self):
        '''Only accept POST request
        '''
        Form.__init__(self)
        
        if self.is_submitted():
            
            # The fields belong to the house start
            self.unit = self.request.values.get('unit');
            self.street = self.request.values.get('street');
            self.postcode = self.request.values.get('postcode');
            
            
            self.description = self.request.values.get('description');
            self.year = self.request.values.get('year');
            
            self.style = self.request.values.get('style');
            
            
            #self.status = self.request.values.get('status'
            n_rooms = self.request.values.get('nrooms')
            if n_rooms != '':
                self.n_rooms = int(n_rooms);
            else:
                self.n_rooms = -1
                
            n_baths = self.request.values.get('nbaths')
            if n_baths != '':
                self.n_baths = int(n_baths)
            else:
                self.n_baths = -1

                 
            n_garages = self.request.values.get('ngarages')
            if n_garages != '':
                self.n_garages = int(n_garages)
            else:
                self.n_garages = -1
                
            self.basement = int(self.request.values.get('basement'))
            
            lots = self.request.values.get('lots')
            if lots != '':
                self.lots = int(lots)
            else:
                self.lots = -1
                
            # optional fields
            living_space = self.request.values.get('living-space')
            if living_space != '':
                self.living_space = int(living_space)
            else:
                self.living_space = -1
                
            self.faces = 0 #int(self.request.values.get('faces'))
            deck = self.request.values.get('deck')
            if deck is None:
                self.deck = 0
            else:
                self.deck = 1
                
            patio = self.request.values.get('patio')
            if patio is None:
                self.patio = 0
            else:
                self.patio = 1
                
            fence = self.request.values.get('fence')
            if fence is None:
                self.fence = 0
            else:
                self.fence = 1
                
            ac = self.request.values.get('ac')
            if ac is None:
                self.ac = 0
            else:
                self.ac = 1
                
            
            self.address_id = self.request.values.get('address_id')
            # The fields belong to the house end
            
            
            # The fields belong to the ad start
            values = self.request.values
            self.title = values['ad-title']
            self.description = values['ad-description']
            
            if values['price'] != '':
                self.price = int(values['price'])
            else:
                self.price = -1
                
            self.manage_by = int(values['ad-by'])
            self.prefer_contact = int(values['prefer-contact'])
                
            self.email = values['email']
            self.phone = values['phone']
            self.term = values['term']
            
            self.action = self.request.values.get('action')

        self.styles = {'single-house':0, "semi-detached":1, "town-house":2, "bangalow":3}
        
        
        self.rules = {"style": { 
                    'required' : [None, True]
                    },
                    "price": { 
                    'required' : [None, True]
                    },
                    "street-no": { 
                    'required' : [None, True]
                    },
                    "street-name": { 
                    'required' : [None, True]
                    }
                }
        

def insert_address(form):
    """ Insert address to database if it is not exist
    """
    address_dao = AddressDao()
    ret_address = address_dao.find_one({'street':form.street})
    if ret_address is None:
        city_dao = CityDao()
        city = city_dao.find_one({'city':'London', 'province':'ON'})
    
        address = Address({'unit':None, 
                           'street':form.street,
                           'postcode':form.postcode,
                           'city': city})
    
        _id = address_dao.insert(address)
        ret_address = address_dao.find_one({'_id':_id})
        
    return ret_address

def insert_house(form, oid=0):
    """ Insert house to database if it is not exist
    """
    ret_address = insert_address(form)
    house_dao = HouseDao()
    ret_house = house_dao.find_one({'name':form.title,'description':form.description})
    if ret_house is None:
        _dict = {'name':form.title,
                       'description':form.description,
                       'year': form.year,
                       'price':form.price, 
                       'status': 0, 
                       'style': form.styles[form.style], 
                       'n_rooms':form.n_rooms, 
                       'n_baths':form.n_baths, 
                       'n_garages':form.n_garages,
                       'basement':form.basement,
                       'lots':form.lots,
                       'living_space':form.living_space,
                       'faces':form.faces, 
                       'deck':form.deck,
                       'patio':form.patio,
                       'fence':form.fence,
                       'ac':form.ac,
                       'address': ret_address}
        
        if oid != 0:
            _dict['_id'] = oid
            
        house = House(_dict)
        _id = house_dao.save(house)
        ret_house = house_dao.find_one({'_id':_id})
    return ret_house

def insert_advertisement(form, _type, category, house, user):
    advertisement = Advertisement({ 'prefer_contact':form.prefer_contact,#0 email, 1 phone
                   'email':form.email,
                   'phone':form.phone,
                   'type':_type, # 0 rent, 1 sell
                   'created':time.time(), 
                   'category':category,
                   'item':house,
                   'user':user})
    
    advertisement_dao = AdvertisementDao()
    _id = advertisement_dao.save(advertisement)
    
def handle_house_ad(form, _type):
    """ Arguments:
            _type -- The int, 0 rent, 1 sell
    """
    errors = form.validate()
    if errors is None:
        # checking the user status table
        session_dao = SessionDao()
        s = session_dao.find_one({'user_id':current_user.id })
        
        if s is not None:
            # Get item oid
            insert_house(form, s.item_id)
            # Add pictures to database
            # Add pictures to advertisement
        else:
            insert_house(form)
            # Add default picture to advertisement
            
        ret_house = insert_house(form)
    
        user_dao = UserDao()
        ret_user = user_dao.find_one({'_id':current_user.id})
        
        # Create 'real estate' category if not exist
        category_dao = CategoryDao()
        ret_category = category_dao.find_one({'name':'house'})
            
        insert_advertisement(form, type, ret_category, ret_house, ret_user)

        _file = form.request.files['property-image']
        fname = secure_filename(_file.filename)
        
        # Current is relative to runner.py, however the target saving path should be in src/static    
        picture_service = PictureService(ret_user.username, ret_category.name, ret_house._id) #Fix me here, should be item!
        
        picture_service.upload(_file)
        picture = Picture({'name':'picture name', 
                'description':'picture description',
                'fname': fname, # only file path can be unique define / find the picture
                'order': 0,
                'created':time.time(), 
                'category':ret_category,
                'item': ret_house})
                  
        # Save file info to database, rename to save_picture_info
        picture_service.save_picture(picture)
        session_dao = SessionDao()
        s = session_dao.find_one({'user_id':current_user.id})
        session_dao.remove(s)
        
    return errors

def rent_apartment(form):
    pass

def rent_room(form):
    pass

def sell_apartment(form):
    pass


@app.route('/manage_property_ads/<string:ad_type>')
@app.route('/manage_property_ads/<string:ad_type>', methods=['GET','POST'])
@login_required
def manage_property_ads(ad_type='rent'):
    form = AdvertisementForm()
    
    if form.is_submitted():
        if form.action == 'edit':
            #category = category_dao.update_category(form.id, form.name, form.description)
            # Load fields from the form
            pass
        elif form.action == 'new': # Get data from fields to save to db
            #category = Category(form.name, form.description)
            #category_dao.add_to_db(category)
            # if form.req[]=='apartment':
            # elif form == 'house':
            #House(name, description, style, _type, price, manage, status=None, nrooms, nbaths, ngarages, basement=None,
            #     lots=None, faces=None, deck=None, patio=None, fence=None, ac=None)
            #elif form=='':
            # Room()
            style = form.style
            errors = None
            if ad_type == 'rent':
                #open rent page
                if style == 'single-house' or style == 'semi-detached' or style == 'town-house':
                    errors = handle_house_ad(form, 0)
                elif style == 'apartment':
                    rent_apartment(form)
                elif style == 'room':
                    rent_room(form)
                return render_template("manage_property_ads.html", ads=None,  action='manage', ad_type='rent',errors=errors)
            elif ad_type == 'sell':
                #open sell page
                if style == 'single-house' or style == 'semi-detached' or style == 'town-house':
                    errors = handle_house_ad(form, 1)
        
            #flash("Image saved.")
            #return redirect(url_for('pictures'))
                return render_template("manage_property_ads.html", ads=None, action='manage', ad_type='sell', errors=errors)
        else:
            # Non submit
            pass
            
    return render_template("manage_property_ads.html", ads=None, action='manage', ad_type=ad_type)      
        
@app.route('/rent_advertisements')
@app.route('/rent_advertisements', methods=['GET','POST'])
@login_required
def rent_advertisements():
    form = AdvertisementForm()
    
    if form.is_submitted():
            #category = category_dao.update_category(form.id, form.name, form.description)
            # Load fields from the form
        pass
        # Get data from fields to save to db
        #category = Category(form.name, form.description)
        #category_dao.add_to_db(category)
        
            #flash("Image saved.")
            #return redirect(url_for('pictures'))
        return render_template("advertisements.html", ads=None, action='post', ad_type='rent')
    else:
        return render_template("advertisements.html", ads=[], action='post', ad_type='rent')

@app.route('/sell_advertisements')
@app.route('/sell_advertisements', methods=['GET','POST'])
@login_required
def sell_advertisements():
    form = AdvertisementForm()
    
    if form.is_submitted():
            #category = category_dao.update_category(form.id, form.name, form.description)
            # Load fields from the form
            # Get data from fields to save to db
            #category = Category(form.name, form.description)
            #category_dao.add_to_db(category)
            #flash("Image saved.")
            #return redirect(url_for('pictures'))
        return render_template("advertisements.html", ads=None, action='post', ad_type='sell')
    else:
        return render_template("advertisements.html", ads=[], action='post', ad_type='sell')







@app.route("/real_estates")
@login_required
def real_estates():
    """Display all real estate advertisement in a list
    """
    ad_service = AdvertisementService()
    infos = ad_service.get_all_infos()
    return render_template("real_estates.html", infos=infos)

    

@app.route('/display_property_rental_ads')
@login_required
def display_property_rental_ads():
    #return render_template("add_category-v1.html", categorys=None)
    
    #category_dao = CategoryDao()
    #_categories = category_dao.all(Category.name)
    if True:#_categories.count() == 0:
        return render_template("manage_property_ads.html", advertisements=None, ad_type='rent')
    else:
        return render_template("manage_property_ads.html", advertisements=[], ad_type='rent')




@app.route('/display_property_sale_ads')
@login_required
def display_property_sale_ads():
    #return render_template("add_category-v1.html", categorys=None)
    
    #category_dao = CategoryDao()
    #_categories = category_dao.all(Category.name)
    if True:#_categories.count() == 0:
        return render_template("manage_property_ads.html", advertisements=None, ad_type='sell')
    else:
        return render_template("manage_property_ads.html", advertisements=[], ad_type='sell')
